package ae.pcfc.etks.online.web.controller.user.internal.workflow.search;

/* $Id: UserPersonController 
 * Copyright (C) 2011, Trakhees
 *  
 *  History
 *
 * Date  			Author 					Remarks
 * -------------------------------------------------------------
 * April 13, 2011 	Neha_Chauhan 	        Created
 *
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.delegate.AppMetaDataDelegate;
import ae.pcfc.etks.online.common.delegate.ClientRegistrationDelegate;
import ae.pcfc.etks.online.common.delegate.ServiceDelegate;
import ae.pcfc.etks.online.common.delegate.UserDelegate;
import ae.pcfc.etks.online.common.util.CommonUtils;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.common.vo.PagingVO;
import ae.pcfc.etks.online.common.vo.ProcessVO;
import ae.pcfc.etks.online.common.vo.SCCompanyVO;
import ae.pcfc.etks.online.common.vo.SCPersonVO;
import ae.pcfc.etks.online.common.vo.SearchCriteriaCompanyVO;
import ae.pcfc.etks.online.common.vo.SearchCriteriaPersonVO;
import ae.pcfc.etks.online.common.vo.WorkflowRequestSearchCriteriaVO;
import ae.pcfc.etks.online.common.vo.WorkflowRequestVO;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.common.Constants;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.controller.user.general.person.UserPersonController;
import ae.pcfc.etks.online.web.model.JQGridJSONModel;
import ae.pcfc.etks.online.web.model.SearchWorkflowRequest;
import ae.pcfc.etks.online.web.util.SecurityUtils;

/**
 * Controller that handles all {@link UserPersonController}-related requests,
 * i.e.: all requests for /user/general/service/*
 * 
 * @author Ismail
 */

@Controller
@RequestMapping(ViewPath.USER_INTERNAL_TRAKHEES_SEARCH_REQUEST)
public class SearchRequestsController extends BaseController {

	private UserDelegate userDelegate;

	@Resource(name = "userDelegate")
	public void setUserDelegate(UserDelegate userDelegate) {
		this.userDelegate = userDelegate;
	}

	private ServiceDelegate serviceDelegate;

	@Resource(name = "serviceDelegate")
	public void setServiceDelegate(ServiceDelegate serviceDelegate) {
		this.serviceDelegate = serviceDelegate;
	}

	private AppMetaDataDelegate appMetaDataDelegate;

	@Resource(name = "appMetaDataDelegate")
	public void setAppMetaDataDelegate(AppMetaDataDelegate appMetaDataDelegate) {
		this.appMetaDataDelegate = appMetaDataDelegate;
	}

	private ClientRegistrationDelegate clientRegistrationDelegate;

	@Resource(name = "clientRegistrationDelegate")
	public void setClientRegistrationDelegate(
			ClientRegistrationDelegate clientRegistrationDelegate) {
		this.clientRegistrationDelegate = clientRegistrationDelegate;
	}

	@ModelAttribute(ConstantsAdmin.STATUS_LIST_MODEL_KEY)
	public List<LabelVO> populateStatusList() {

		List<LabelVO> labelList = new ArrayList<LabelVO>();

		LabelVO labelVO = null;

		labelVO = new LabelVO();
		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.IN_PROGRESS);
		labelVO.setLabelEn(this.getMessageSource().getMessage(
				"msg.workflow.status.in.progress", null, Locale.ENGLISH));
		labelVO.setLabelAr(this.getMessageSource().getMessage(
				"msg.workflow.status.in.progress", null,
				new Locale(Constants.LOCALE_ARABIC)));
		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.APPROVE);
		labelVO.setLabelEn(this.getMessageSource().getMessage(
				"msg.workflow.status.approved", null, Locale.ENGLISH));
		labelVO.setLabelAr(this.getMessageSource().getMessage(
				"msg.workflow.status.approved", null,
				new Locale(Constants.LOCALE_ARABIC)));
		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.REJECT);
		labelVO.setLabelEn(this.getMessageSource().getMessage(
				"msg.workflow.status.rejected", null, Locale.ENGLISH));
		labelVO.setLabelAr(this.getMessageSource().getMessage(
				"msg.workflow.status.rejected", null,
				new Locale(Constants.LOCALE_ARABIC)));
		labelList.add(labelVO);
		return labelList;
	}

	@ModelAttribute(ConstantsAdmin.REQUEST_TYPE_LIST_MODEL_KEY)
	public List<LabelVO> populateRequestTypeList() {

		List<ProcessVO> processListVos = this.serviceDelegate.getProcessList();
		if (processListVos != null) {
			List<LabelVO> labelList = new ArrayList<LabelVO>();
			labelList.add(new LabelVO());
			LabelVO labelVO = null;
			for (ProcessVO processVO : processListVos) {
				labelVO = new LabelVO();
				labelVO.setId(processVO.getProcessCode());
				labelVO.setLabelEn(processVO.getProcessDesc());
				labelVO.setLabelAr(processVO.getProcessDescA());
				labelList.add(labelVO);
			}
			return labelList;
		}
		return null;
	}

	@ModelAttribute(ConstantsAdmin.CLIENT_TYPES_MODEL_KEY)
	public List<LabelVO> populateClientTypesListModel(Locale locale) {

		List<LabelVO> labelList = new ArrayList<LabelVO>();

		LabelVO labelVO = new LabelVO();
		labelVO.setId(ConstantsAdmin.SEARCH_CLIENT);
		labelVO.setLabelAr(getMessageSource().getMessage("label.search.client",
				null, locale));
		labelVO.setLabelEn(getMessageSource().getMessage("label.search.client",
				null, locale));
		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId(ConstantsAdmin.SEARCH_NON_CLIENT);
		labelVO.setLabelAr(getMessageSource().getMessage(
				"label.search.nonclient", null, locale));
		labelVO.setLabelEn(getMessageSource().getMessage(
				"label.search.nonclient", null, locale));
		labelList.add(labelVO);

		return labelList;
	}

	@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(
			@ModelAttribute(value = ConstantsAdmin.SEARCH_WORKFLOW_REQUEST_MODEL_KEY) SearchWorkflowRequest command) {
		command.setClientType(ConstantsAdmin.SEARCH_CLIENT);
	}

	@RequestMapping(value = "/client.json", method = RequestMethod.GET)
	public @ResponseBody
	String searchClient(
			@RequestParam(value = "term", required = true) String term,
			Locale locale) {
		List<String> clients = new ArrayList<String>();
		boolean arabicLocale = false;
		SearchCriteriaCompanyVO searchCriteriaCompanyVO = new SearchCriteriaCompanyVO();
		if (locale.equals(Locale.ENGLISH)) {
			searchCriteriaCompanyVO.setCompanyNameEng(term);
		} else {
			arabicLocale = true;
			searchCriteriaCompanyVO.setCompanyNameArb(term);
		}
		List<SCCompanyVO> companySearchResult = this.clientRegistrationDelegate
				.findCompany(searchCriteriaCompanyVO);
		if (companySearchResult != null && companySearchResult.size() > 0) {
			for (int i = 0; i < companySearchResult.size()
					&& i < ConstantsAdmin.MAX_SEARCH_RESULT_SIZE; i++) {
				SCCompanyVO scCompanyVO = companySearchResult.get(i);
				clients.add("{\"id\":\""
						+ scCompanyVO.getStrTrakheesId()
						+ "\", \"label\":\""
						+ scCompanyVO.getStrTrakheesId()
						+ " : "
						+ (arabicLocale ? scCompanyVO.getStrNameARB().replace(
								"\"", "") : scCompanyVO.getStrNameENG()
								.replace("\"", "")) + "\", \"value\":\""
						+ scCompanyVO.getStrTrakheesId() + "\"}");
			}
			if (companySearchResult.size() >= ConstantsAdmin.MAX_SEARCH_RESULT_SIZE) {
				return clients.toString();
			}
		}
		SearchCriteriaPersonVO searchCriteriaPersonVO = new SearchCriteriaPersonVO();
		if (locale.equals(Locale.ENGLISH)) {
			searchCriteriaPersonVO.setNameEng(term);
		} else {
			arabicLocale = true;
			searchCriteriaPersonVO.setNameArb(term);
		}
		List<SCPersonVO> personSearchResult = this.clientRegistrationDelegate
				.findPerson(searchCriteriaPersonVO);
		if (personSearchResult != null && personSearchResult.size() > 0) {
			for (int i = 0, j = clients.size(); i < personSearchResult.size()
					&& j < ConstantsAdmin.MAX_SEARCH_RESULT_SIZE; i++, j++) {
				SCPersonVO scPersonVO = personSearchResult.get(i);
				clients.add("{\"id\":\""
						+ scPersonVO.getStrTrakheesId()
						+ "\", \"label\":\""
						+ scPersonVO.getStrTrakheesId()
						+ " : "
						+ (arabicLocale ? scPersonVO.getStrNameARB().replace(
								"\"", "") : scPersonVO.getStrNameENG().replace(
								"\"", "")) + "\", \"value\":\""
						+ scPersonVO.getStrTrakheesId() + "\"}");
			}
		}
		return clients.toString();
	}

	@RequestMapping(value = "/requestStatus.json", method = RequestMethod.GET)
	public ResponseEntity<String> getRequestStatus(
			@RequestParam(value = "term", required = true) String term,
			Locale locale) {

		List<LabelVO> requestStatus = this.appMetaDataDelegate
				.searchRequestStatus(term);
		List<String> requestStatusList = new ArrayList<String>();

		if (requestStatus != null && requestStatus.size() > 0) {
			for (LabelVO labelVO : requestStatus) {
				/*
				 * requestStatusList.add("{\"id\":\"" + labelVO.getLabelEn() +
				 * "\", \"label\":\"" + labelVO.getLabelEn() +" : "+
				 * labelVO.getLabelAr() + "" + "\", \"value\":\"" +
				 * (locale.equals(new Locale("ar"))) != null?
				 * labelVO.getLabelAr(): labelVO.getLabelEn() + "\"}");
				 */

				requestStatusList.add("{\"id\":\"" + labelVO.getLabelEn() + ""
						+ "\", \"label\":\"" + labelVO.getLabelEn() + "-"
						+ labelVO.getLabelAr() + "\", \"value\":\""
						+ labelVO.getLabelEn() + "\"}");

			}
		} else {

			requestStatusList.add("{\"id\":\""
					+ ""
					+ "\", \"label\":\""
					+ getMessageSource().getMessage("msg.search.empty", null,
							locale) + "" + "\", \"value\":\"" + "" + "\"}");

		}

		// return requestStatusList.toString();

		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.set("Content-Type", "application/json; charset=UTF-8");
		
		return new ResponseEntity<String>(requestStatusList.toString(),
				responseHeaders, HttpStatus.CREATED);

	}

	@RequestMapping(value = "/form.htm", method = RequestMethod.POST)
	public @ResponseBody
	JQGridJSONModel formSubmit(
			HttpServletRequest request,
			@ModelAttribute(value = ConstantsAdmin.SEARCH_WORKFLOW_REQUEST_MODEL_KEY) SearchWorkflowRequest command,
			@RequestParam(value = "page", required = true) String page,
			@RequestParam(value = "rows", required = true) String rows,
			@RequestParam(value = "sidx", required = true) String sidx,
			@RequestParam(value = "sord", required = true, defaultValue = "desc") String sord,
			@RequestParam(value = "_search", required = false) String isSearch,
			@RequestParam(value = "searchField", required = false) String searchField,
			@RequestParam(value = "searchOper", required = false) String searchOper,
			@RequestParam(value = "searchString", required = false) String searchString,
			Locale locale) {
		List<String> requestParameterNames = Collections
				.list((Enumeration<String>) request.getParameterNames());

		for (String parameterName : requestParameterNames) {
			System.out.println("parameterName = " + parameterName);

		}

		System.out.println("page==" + page);
		System.out.println("rows==" + rows);
		System.out.println("sidx==" + sidx);
		System.out.println("searchField==" + searchField);
		System.out.println("searchOper==" + searchOper);
		System.out.println("searchString==" + searchString);
		System.out.println("isSearch==" + isSearch);
		System.out.println("sord==" + sord);

		JQGridJSONModel result = new JQGridJSONModel();

		WorkflowRequestSearchCriteriaVO searchCriteria = new WorkflowRequestSearchCriteriaVO();
		getMapper().map(command, searchCriteria);
		List<WorkflowRequestVO> requests = this.appMetaDataDelegate
				.searchWorkflowRequests(searchCriteria);

		Integer pageIndx = 1, count = 0, totalpages = 0, start = 0;
		if (requests != null) {
			count = requests.size();
			final String sortField = sidx;
			int sortOrder = 1;
			if (ConstantsAdmin.DESC_ORDER.equalsIgnoreCase(sord)) {
				sortOrder = -1;
			}
			final int fSortOrder = sortOrder;
			Collections.sort(requests, new Comparator<WorkflowRequestVO>() {
				public int compare(WorkflowRequestVO o1, WorkflowRequestVO o2) {
					/*
					 * int cmp =
					 * o1.getStrProcessCode().compareTo(o2.getStrProcessCode());
					 * if(cmp != 0){ return cmp; }else{
					 */
					if (sortField != null && sortField.contains("Id")) {
						return CommonUtils.getLongFieldValue(o1, sortField)
								.compareTo(
										CommonUtils.getLongFieldValue(o2,
												sortField))
								* fSortOrder;
					} else {
						return CommonUtils.getStringFieldValue(o1, sortField)
								.compareTo(
										CommonUtils.getStringFieldValue(o2,
												sortField))
								* fSortOrder;
					}
					/* } */
				}
			});
		}

		Integer limit = 40;
		try {
			pageIndx = Integer.parseInt(page);
		} catch (Exception nullexp) {
			pageIndx = 1;
		}
		try {
			limit = Integer.parseInt(rows);
		} catch (Exception nullexp) {
			pageIndx = 10;
		}

		if (count > 0)
			totalpages = (int) Math.ceil(((float) count) / (float) limit);
		else
			totalpages = 0;

		if (pageIndx > totalpages)
			pageIndx = totalpages;

		start = (limit * pageIndx) - limit;
		result.setPage(pageIndx.toString());
		result.setRecords(count + "");
		result.setTotal(totalpages + "");

		PagingVO pagingVO = new PagingVO();
		pagingVO.setStart(start);
		pagingVO.setSearchfieldName(searchField);
		pagingVO.setSerachString(searchString);
		pagingVO.setSortFieldName(sidx);
		pagingVO.setSortOrder(sord);
		pagingVO.setPageNumber(pageIndx);
		pagingVO.setPageSize(limit);

		if (requests != null) {
			// for (WorkflowRequestVO requestVO : requests) {
			for (int idx = start, elmts = 0; idx < requests.size()
					&& elmts < limit; idx++, elmts++) {
				WorkflowRequestVO requestVO = requests.get(idx);
				if (requestVO != null) {
					List<String> cells = new ArrayList<String>();
					cells.add(requestVO.getStrApplicationId());
					cells.add(requestVO.getStrClientRefNo());
					cells.add(requestVO.getStrWFIncidentId());
					cells.add(requestVO.getStrProcessCode());
					cells.add(requestVO.getStrProcessCodeDescAr());
					cells.add(requestVO.getStrProcessCodeDescEn());
					cells.add(requestVO.getStrStatusDescAr());
					cells.add(requestVO.getStrStatusDescEn());
					if (StringUtils.isNotBlank(requestVO
							.getStrApplicationLink())) {
						cells.add(requestVO.getStrApplicationLink());
					} else {
						cells.add("");
					}
					/*
					 * cells.add(requestVO.getStrProcessStep());
					 * cells.add(requestVO.getStrProcessStepDescAr());
					 * cells.add(requestVO.getStrProcessStepDescEn());
					 */
					if (StringUtils.isNotBlank(requestVO.getStrApplicationId())) {
						cells.add(SecurityUtils.encryptQueryParam(requestVO
								.getStrApplicationId()));
						// cells.add(requestVO.getStrApplicationId());
					} else {
						cells.add("");
					}
					
					if(!StringUtils.isBlank(requestVO.getStrWFIncidentId()))
					{
						 cells.add(SecurityUtils.encryptQueryParam(requestVO.getStrWFIncidentId()));						  
					}
					else{
						 cells.add(""); 
					}
					/*
					 * 
					 * if(!StringUtils.isBlank(requestVO.getStrProcessStep())){
					 * //cells.add(SecurityUtils.encryptQueryParam(requestVO.
					 * getStrProcessStep()));
					 * cells.add(requestVO.getStrProcessStep()); }else{
					 * cells.add(""); }
					 */
					result.addRows(
							requestVO.getStrApplicationId()
									+ requestVO.getStrProcessStep(), cells);
				}
			}
			// }
		}
		return result;
	}
}
